#include <iostream>
#include <pthread.h>
#include <string>
#include <vector>
#include <unistd.h>

#define NUM 5
int cnt = 1000;

pthread_mutex_t glock = PTHREAD_MUTEX_INITIALIZER;//互斥锁
pthread_cond_t gcond  = PTHREAD_COND_INITIALIZER;//条件变量

//等待是在加锁和解锁之间等，临界资源不满足导致进程进行等待

void *threadrun(void *arg)
{
    std::string name = static_cast<const char*>(arg); 
    while(true)
    {
        //pthread_mutex_lock基本功能
        // 加锁操作：尝试获取互斥量的所有权。
        // 若锁处于未锁定状态：当前线程立即获得锁，函数返回。
        // 若锁已被其他线程持有：当前线程进入阻塞状态，直到锁被释放。

        //pthread_cond_wait基本功能
        //调用 pthread_cond_wait 的线程会释放关联的互斥量（Mutex），并进入阻塞状态，直到其他线程发出条件满足的信号。
        //当线程被唤醒时，它会自动重新获取互斥量，并继续执行。

        pthread_mutex_lock(&glock);
        pthread_cond_wait(&gcond,&glock);
        
        std::cout << name << "计算: " << cnt << std::endl;
        cnt++;
        pthread_mutex_unlock(&glock);
    }
}

int main()
{
    //主线程与工作线程并发执行，互不干扰
    std::vector<pthread_t> threads;
    for(int i = 0;i < NUM;i++)
    {
        pthread_t tid;
        char *name = new char[64];
        snprintf(name,64,"thread-%d",i);
        int n = pthread_create(&tid,nullptr,threadrun,name);
        if(n != 0)
            continue;
        threads.push_back(tid);    
        //sleep(1);
        //free(name);
        //name = NULL;
    }

    sleep(3);

    //每隔1秒唤醒已经阻塞线程
    while(true)
    {
        // std::cout << "唤醒一个线程..." << std::endl;
        //pthread_cond_signal(&gcond);
        std::cout << "唤醒所有线程..." << std::endl;
        pthread_cond_broadcast(&gcond);
        sleep(1);
    }

    for(auto &id : threads)
    {
        int m = pthread_join(id,nullptr);
        (void)m;
    }
    return 0;
}